package com.smsc.headend.task.engine.handler.impl.whitelist;

import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.module.asset.dto.MeterDTO;
import com.smsc.headend.module.asset.entity.ComEntity;
import com.smsc.headend.module.asset.entity.DeviceRelation;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.report.entity.LogUnRegisterMeterHis;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.task.enums.TaskType;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.mapper.DeviceRelationMapper;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import com.smsc.headend.task.engine.service.asset.AssetService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wxh
 * @date 2020/12/07
 */
@Slf4j
public class DeleteMeterListHandler implements TaskHandler {
    @Autowired
    FeignAssetManagementService assetManagementService;
    @Autowired
    TaskDAO taskDAO;
    @Autowired
    DeviceRelationMapper deviceRelationMapper;
    @Autowired
    AssetService assetService;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData cosemData, String actionResult) throws UDISTaskHandlerException {
        if("Success".equals(actionResult)) {
            Map<String, Object> map = JSONUtil.toBean(task.getParamJson(), Map.class);
            List meterIds1 = (List) map.get("meterIds");
            List<Long> meterIds = (List<Long>) meterIds1.stream().map(o -> Long.valueOf(String.valueOf(o))).collect(Collectors.toList());
            for (Long meterId : meterIds) {
                if(meterId.equals(-1L)) {
                    continue;
                }
                DeviceRelation deviceRelation = deviceRelationMapper.selectById(meterId);
                if(deviceRelation != null) {
                    Long parentId = deviceRelation.getParentId();
                    ComEntity com = assetManagementService.getComByDeviceId(parentId);
                    if(com != null && !com.getComId().equals(task.getComId())) {
                        continue;
                    }
                }
                MeterDTO meterDTO = new MeterDTO();
                meterDTO.setMeterId(meterId);
                meterDTO.setMountStatus(Meter.MeterMountStatus.Unmount.getCode());
                if(StrUtil.equalsAny(task.getTaskType(), TaskType.Asset_Import_Provision.toString(), TaskType.UAA_Provision.toString())) {
                    meterDTO.setManageStatus(Meter.MeterManageStatus.UnManage.getCode());
                    meterDTO.setValidStatus(Meter.MeterValidStatus.Invalid.getCode());
                } else if (StrUtil.equalsAny(task.getTaskType(), TaskType.DcuPushUnRegisterMeter.toString(), TaskType.DcuManualUnRegisterMeter.toString())) {
                    assetManagementService.saveUnregisterMeterHis(meterId, deviceRelation.getParentId(), task.getTaskNo(), LogUnRegisterMeterHis.ActionType.DeleteMeterList.getCode(),
                            task.getTaskType().equals(TaskType.DcuPushUnRegisterMeter.toString()) ? LogUnRegisterMeterHis.UnRegisterSrc.Auto.getCode() : LogUnRegisterMeterHis.UnRegisterSrc.Manual.getCode(),
                            LogUnRegisterMeterHis.UnRegisterStatus.SUCCESS.getCode(), null, SystemClock.now() / 1000, "Delete MeterList Completed");
                }
                assetManagementService.updateMeterStatus(meterDTO);
            }

            taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), String.valueOf(task.getComId()), meterIds1,
                    Long.valueOf(1 * 60 * 60), true);
        } else {
            taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), String.valueOf(task.getComId()), actionResult,
                    Long.valueOf(1 * 60 * 60), false);
        }

        return 1;
    }

    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), "message", message, 3600l, false);
        if (StrUtil.equalsAny(task.getTaskType(), TaskType.DcuPushUnRegisterMeter.toString(), TaskType.DcuManualUnRegisterMeter.toString())) {
            log.error("failed message {}", message);
            // 记录更新自注册流程失败的record
            Map<String, Object> map = JSONUtil.toBean(task.getParamJson(), Map.class);
            List<Long> meterIds = (List<Long>) ((List) map.get("meterIds")).stream().map(o -> Long.valueOf(String.valueOf(o))).collect(Collectors.toList());
            ComEntity comEntity = assetService.getComById(task.getComId());
            for (Long meterId : meterIds) {
                Meter meter = assetManagementService.getMeterById(meterId);
                assetManagementService.saveUnRegisterRecord(meter.getMfgSn(), comEntity.getDeviceId(), null, "Delete Meter List Failed");
                assetManagementService.saveUnregisterMeterHis(meterId, comEntity.getDeviceId(), task.getTaskNo(), LogUnRegisterMeterHis.ActionType.DeleteMeterList.getCode(),
                        task.getTaskType().equals(TaskType.DcuPushUnRegisterMeter.toString()) ? LogUnRegisterMeterHis.UnRegisterSrc.Auto.getCode() : LogUnRegisterMeterHis.UnRegisterSrc.Manual.getCode(), LogUnRegisterMeterHis.UnRegisterStatus.FAILED.getCode(), null, SystemClock.now() / 1000, message);
            }
        }
        return -1;
    }
}
